package com.itheima.mq.rabbitmq.producer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @program: 基础代码
 * @description: 发送消息的类
 * @author: zhanghz001
 * @create: 2021-05-07 17:53
 **/
@Component
public class RabbitmqSendMsgConfirm implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {
    // 定义日志记录对象
    private static final Logger LOGGER =
            LoggerFactory.getLogger(RabbitmqSendMsgConfirm.class);
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    //发送消息
    public void sendMsg(String msg, String exchangeName, String routingKey) {
        
        //发送消息是否成功的回调
        rabbitTemplate.setConfirmCallback(this);
        
        //添加return确认机制的回调函数
        rabbitTemplate.setReturnCallback(this);
        //设置发送消息是否成功的回调
        
        CorrelationData correlationData = new CorrelationData(msg);
        rabbitTemplate.convertAndSend(exchangeName, routingKey,
                msg
                , message -> {
                    //持久化操作
                    message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                    return message;
                }, correlationData);
    }
    
    /**
     * CorrelationData: 每个发送的消息都需要配备一个 CorrelationData 相关数据对象，
     * CorrelationData 对象内部只有一个 id 属性，用来表示当前消息唯一性。
     *
     * @param correlationData
     * @param ack
     * @param cause
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            LOGGER.info("消息发送成功");
        } else {
            LOGGER.info("消息发送失败");
        }
    }
    
    // 当消息没有被交换机投递到指定的队列的回调函数
    //失败才调用的
    @Override
    public void returnedMessage(Message message, int replyCode, String
            replyText, String exchange, String routingKey) {
        LOGGER.info("消息没有被投递到指定的队列 ---> " + new String(message.getBody()));
    }
}
